#include "widget.h"
#include "ui_widget.h"

QTimer *m_timer = new QTimer; //新建定时器  m_timer

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    modbusDevice = new QModbusRtuSerialMaster();
    portList = new SerialPortList(200);
    portList->ScanStart();

    //串口配置
    modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,QSerialPort::Baud115200);

    modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,QSerialPort::NoParity);

    modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,QSerialPort::Data8);

    modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,QSerialPort::OneStop);

    modbusDevice->setTimeout(1000);

    modbusDevice->setNumberOfRetries(3);

    connect(m_timer, &QTimer::timeout, this, &Widget::onTimeout);//定时器启动
    connect(portList, SIGNAL(onNewSerialPort(QStringList)),this,SLOT(onNewPortList(QStringList)));//自动扫描端口
}

void Widget::onTimeout()//定时器超时处理
{
    ui->connectButton->setText("连接中...");
    static int listCont = 0;
    QModbusReply *reply;
    if(!modbusDevice){
        return;
    }
    if(listCont > portlist.size()){
        return;
    }

    if( modbusDevice->state() != QModbusDevice::ConnectedState){
        modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,portlist.at(listCont++));//portlist为端口列表
        if (!modbusDevice->connectDevice()){
            qDebug() << " 连接失败";
        }
        else {
            //发送读请求读01设备的01寄存器
            reply = modbusDevice->sendReadRequest(QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 1, 1),1);
            connect(reply, &QModbusReply::finished, this, [this, reply]()//收到modbus finised信号
                    {
                           portState  = reply->result().value(0);  //读取下位机设备信息
                           qDebug() <<"状态："<< portState;
                    });
        }
    }
    else{
        //若01设备的01寄存器返回1，则为有效设备。进行连接
        //若无返回portState为0，为无效设备，断开断开连接
        //portState默认状态为 -1
        if(portState != -1){
            if(portState == 0){
                modbusDevice->disconnectDevice();
                return;
            }
            if(portState == 1 ){
                qDebug() << "连接成功";
                m_timer->stop();
                ui->connectButton->setText("断开");
                portState = -1;
                listCont = 0;
                return;
            }
            reply->result().values().clear();
            portState = -1;
        }
        else return;
    }
}


void Widget::on_connectButton_clicked()//连接按钮
{
    if( ui->connectButton->text() == "连接"){
        m_timer->start(500);//开启定时器500ms轮询

    }
    else{
        modbusDevice->disconnectDevice();
        ui->connectButton->setText("连接");
    }
}
void Widget::onNewPortList(QStringList portName){//自动刷新端口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
        //过滤ttl型号,按需修改 我这里使用CP2101，故为Silicon Labs CP210x USB to UART Bridge   其他型号可在设备管理器查看
        if(info.description() == "Silicon Labs CP210x USB to UART Bridge"  )
        portlist<<info.portName();
    }
    /*****打印筛选后端口列表***********
    for( int i = 0;i < portlist.size();i++){
        qDebug() << portlist.at(i);
    }
    **************************/
}

Widget::~Widget()
{
    delete ui;
}
